home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-9.10-netbook-remix-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / deluge / metafile.py < prev    next >
Text File  |  2009-06-16  |  7KB  |  219 lines

  1. # Taken from http://download.bittorrent.com/dl/BitTorrent-5.3-GPL.tar.gz
  2. #
  3. # This program is free software: you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation, either version 3 of the License, or
  6. # (at your option) any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  15.  
  16. # Written by Bram Cohen
  17. # Modifications for use in Deluge by Andrew Resch 2008
  18.  
  19. import os
  20. import os.path
  21. import sys
  22. import time
  23. from sha import sha
  24.  
  25. from deluge.bencode import bencode
  26. from deluge.log import LOG as log
  27.  
  28. ignore = ['core', 'CVS', 'Thumbs.db', 'desktop.ini']
  29.  
  30. noncharacter_translate = {}
  31. for i in xrange(0xD800, 0xE000):
  32.     noncharacter_translate[i] = ord('-')
  33. for i in xrange(0xFDD0, 0xFDF0):
  34.     noncharacter_translate[i] = ord('-')
  35. for i in (0xFFFE, 0xFFFF):
  36.     noncharacter_translate[i] = ord('-')
  37.  
  38. def gmtime():
  39.     return time.mktime(time.gmtime())
  40.  
  41. def get_filesystem_encoding():
  42.     return sys.getfilesystemencoding()
  43.  
  44. def decode_from_filesystem(path):
  45.     encoding = get_filesystem_encoding()
  46.     if encoding == None:
  47.         assert isinstance(path, unicode), "Path should be unicode not %s" % type(path)
  48.         decoded_path = path
  49.     else:
  50.         assert isinstance(path, str), "Path should be str not %s" % type(path)
  51.         decoded_path = path.decode(encoding)
  52.  
  53.     return decoded_path
  54.  
  55. def dummy(v):
  56.     pass
  57.  
  58. def make_meta_file(path, url, piece_length, progress=dummy,
  59.                    title=None, comment=None, safe=None, content_type=None,
  60.                    target=None, url_list=None, name=None, private=False,
  61.                    created_by=None, httpseeds=None):
  62.     data = {'creation date': int(gmtime())}
  63.     if url:
  64.         data['announce'] = url.strip()
  65.     a, b = os.path.split(path)
  66.     if not target:
  67.         if b == '':
  68.             f = a + '.torrent'
  69.         else:
  70.             f = os.path.join(a, b + '.torrent')
  71.     else:
  72.         f = target
  73.     info = makeinfo(path, piece_length, progress, name, content_type, private)
  74.  
  75.     #check_info(info)
  76.     h = file(f, 'wb')
  77.  
  78.     data['info'] = info
  79.     if title:
  80.         data['title'] = title
  81.     if comment:
  82.         data['comment'] = comment
  83.     if safe:
  84.         data['safe'] = safe
  85.     if url_list:
  86.         data['url-list'] = url_list
  87.     if created_by:
  88.         data['created by'] = created_by
  89.     if httpseeds:
  90.         data['httpseeds'] = httpseeds
  91.  
  92.     h.write(bencode(data))
  93.     h.close()
  94.  
  95. def calcsize(path):
  96.     total = 0
  97.     for s in subfiles(os.path.abspath(path)):
  98.         total += os.path.getsize(s[1])
  99.     return total
  100.  
  101. def makeinfo(path, piece_length, progress, name = None,
  102.              content_type = None, private=False):  # HEREDAVE. If path is directory,
  103.                                     # how do we assign content type?
  104.     def to_utf8(name):
  105.         if isinstance(name, unicode):
  106.             u = name
  107.         else:
  108.             try:
  109.                 u = decode_from_filesystem(name)
  110.             except Exception, e:
  111.                 raise Exception('Could not convert file/directory name %r to '
  112.                                   'Unicode. Either the assumed filesystem '
  113.                                   'encoding "%s" is wrong or the filename contains '
  114.                                   'illegal bytes.' % (name, get_filesystem_encoding()))
  115.  
  116.         if u.translate(noncharacter_translate) != u:
  117.             raise Exception('File/directory name "%s" contains reserved '
  118.                               'unicode values that do not correspond to '
  119.                               'characters.' % name)
  120.         return u.encode('utf-8')
  121.     path = os.path.abspath(path)
  122.     piece_count = 0
  123.     if os.path.isdir(path):
  124.         subs = subfiles(path)
  125.         subs.sort()
  126.         pieces = []
  127.         sh = sha()
  128.         done = 0
  129.         fs = []
  130.         totalsize = 0.0
  131.         totalhashed = 0
  132.         for p, f in subs:
  133.             totalsize += os.path.getsize(f)
  134.         if totalsize >= piece_length:
  135.             import math
  136.             num_pieces = math.ceil(float(totalsize) / float(piece_length))
  137.         else:
  138.             num_pieces = 1
  139.  
  140.         for p, f in subs:
  141.             pos = 0
  142.             size = os.path.getsize(f)
  143.             p2 = [to_utf8(n) for n in p]
  144.             if content_type:
  145.                 fs.append({'length': size, 'path': p2,
  146.                            'content_type' : content_type}) # HEREDAVE. bad for batch!
  147.             else:
  148.                 fs.append({'length': size, 'path': p2})
  149.             h = file(f, 'rb')
  150.             while pos < size:
  151.                 a = min(size - pos, piece_length - done)
  152.                 sh.update(h.read(a))
  153.                 done += a
  154.                 pos += a
  155.                 totalhashed += a
  156.  
  157.                 if done == piece_length:
  158.                     pieces.append(sh.digest())
  159.                     piece_count += 1
  160.                     done = 0
  161.                     sh = sha()
  162.                 progress(piece_count, num_pieces)
  163.             h.close()
  164.         if done > 0:
  165.             pieces.append(sh.digest())
  166.  
  167.         if name is not None:
  168.             assert isinstance(name, unicode)
  169.             name = to_utf8(name)
  170.         else:
  171.             name = to_utf8(os.path.split(path)[1])
  172.  
  173.         return {'pieces': ''.join(pieces),
  174.             'piece length': piece_length, 'files': fs,
  175.             'name': name,
  176.             'private': private}
  177.     else:
  178.         size = os.path.getsize(path)
  179.         if size >= piece_length:
  180.             num_pieces = size / piece_length
  181.         else:
  182.             num_pieces = 1
  183.  
  184.         pieces = []
  185.         p = 0
  186.         h = file(path, 'rb')
  187.         while p < size:
  188.             x = h.read(min(piece_length, size - p))
  189.             pieces.append(sha(x).digest())
  190.             piece_count += 1
  191.             p += piece_length
  192.             if p > size:
  193.                 p = size
  194.             progress(piece_count, num_pieces)
  195.         h.close()
  196.         if content_type is not None:
  197.             return {'pieces': ''.join(pieces),
  198.                 'piece length': piece_length, 'length': size,
  199.                 'name': to_utf8(os.path.split(path)[1]),
  200.                 'content_type' : content_type,
  201.                 'private': private }
  202.         return {'pieces': ''.join(pieces),
  203.             'piece length': piece_length, 'length': size,
  204.             'name': to_utf8(os.path.split(path)[1]),
  205.             'private': private}
  206.  
  207. def subfiles(d):
  208.     r = []
  209.     stack = [([], d)]
  210.     while stack:
  211.         p, n = stack.pop()
  212.         if os.path.isdir(n):
  213.             for s in os.listdir(n):
  214.                 if s not in ignore and not s.startswith('.'):
  215.                     stack.append((p + [s], os.path.join(n, s)))
  216.         else:
  217.             r.append((p, n))
  218.     return r
  219.